using System;

using MettleSystems.dashCommerce.Core.Serialization;

namespace MettleSystems.dashCommerce.Core.Configuration
{
	public class DatabaseConfigurationProvider
	{

		#region Constants

		private const string CONFIGURATION_SECTION_NAME = "configurationSectionName";
		private const string NAME = "name";
		private const string OBJ = "obj";
		private const string USERNAME = "userName";

		#endregion

		#region Methods

		#region Public

		/// <summary>
		/// Fetches the configuration by id.
		/// </summary>
		/// <param name="configurationDataId">The configuration data id.</param>
		/// <returns></returns>
		public virtual ConfigurationDatum FetchConfigurationById(int configurationDataId)
		{
			Validator.ValidateIntegerIsGreaterThanZero(configurationDataId,
			                                           ConfigurationContants.ARGUMENT_CONFIGURATION_DATA_ID);

			ConfigurationDatumCollection configurationDatumCollection =
				new ConfigurationDatumController().FetchByID(configurationDataId);

			ConfigurationDatum configurationDatum = null;
			if (configurationDatumCollection.Count == 1) {
				configurationDatum = configurationDatumCollection[0];
			}
			return configurationDatum;
		}

		/// <summary>
		/// Fetches the configuration by name.
		/// </summary>
		/// <param name="configurationSectionName">Name of the configuration section.</param>
		/// <returns></returns>
		public virtual object FetchConfigurationByName(string configurationSectionName)
		{
			Validator.ValidateStringArgumentIsNotNullOrEmptyString(configurationSectionName, CONFIGURATION_SECTION_NAME);

			ConfigurationDatum configurationDatum =
				new ConfigurationDatumController().FetchConfigurationByName(configurationSectionName);

			object obj = null;

			if (configurationDatum != null) {
				Serializer serializer = new Serializer();
				obj = serializer.DeserializeObject(configurationDatum.ValueX, configurationDatum.Type);
			}
			return obj;
		}

		/// <summary>
		/// Saves the configuration.
		/// </summary>
		/// <param name="name">The name.</param>
		/// <param name="obj">The obj.</param>
		/// <param name="userName">Name of the user.</param>
		/// <returns></returns>
		public virtual int SaveConfiguration(string name, object obj, string userName)
		{
			Validator.ValidateStringArgumentIsNotNullOrEmptyString(name, NAME);
			Validator.ValidateArgumentIsSerializable(obj, OBJ);
			Validator.ValidateStringArgumentIsNotNullOrEmptyString(userName, USERNAME);

			Serializer serializer = new Serializer();
			string xml = serializer.SerializeObject(obj, obj.GetType());

			ConfigurationDatum configurationDatum = new ConfigurationDatum(ConfigurationDatum.Columns.Name, name);
			configurationDatum.Name = name;
			configurationDatum.Type = obj.GetType().AssemblyQualifiedName;
			configurationDatum.ValueX = xml.Trim();
			if (configurationDatum.ConfigurationDataId == 0) {
				configurationDatum.CreatedDate = DateTime.UtcNow;
			}
			else {
				configurationDatum.ModifiedDate = DateTime.UtcNow;
			}
			configurationDatum.Save(userName);
			return configurationDatum.ConfigurationDataId;
		}

		#endregion

		#endregion

	}
}
